#include "aerial\Game\GameObject\FlyObject\FlyObject.h"

#include "aerial\Game\GameObject\Equipment\Weapon.h"
#include "aerial\Game\GameObject\Equipment\Shield.h"
#include "aerial\Game\GameObject\Equipment\Propeller.h"

#include "aerial\Core\NetIO.h"

#include "aerial\Core\NetMessage.h"

#include "aerial\Game\GameScene\BattleScene.h"

hgeInputEvent* FlyObject::inputEvent = 0;
BattleScene* FlyObject::battleScene = 0;

void FlyObject::SetInputEvent(hgeInputEvent* _inputEvent) { inputEvent = _inputEvent; }

void FlyObject::SetBattleScene(BattleScene* _battleScene) { battleScene = _battleScene; }

FlyObject::FlyObject(float x, float y, float A, int _id, const char* usrname, uchar _side)
	: GameObject(x, y, _id, A) 
	, username(usrname), status(0), d_status(0), shield(0), side(_side)
{
}

FlyObject::~FlyObject() { 
	delete shield; 
	delete propeller; 
}

bool FlyObject::update(float dt)
{
	HandleShield();
	propeller->update(dt);
	if (shield->update(dt)) SetState(0, M_SHIELD); 
	GameObject::update(dt);
	return false;
}

void FlyObject::SerializationFull(BitStream* bso)
{
	bso->Write(id);
	//bso->Write(status);
	//bso->Write(d_status);
	bso->Write(power);
	bso->Write(T.x);
	bso->Write(T.y);
	bso->Write(V.x);
	bso->Write(V.y);
	bso->Write(A);
}

void FlyObject::DeSerializationFull(BitStream* bsi)
{
	uchar tid;
	bsi->Read(tid);
	if (tid != id) return;
	//bsi->Read(status);
	//bsi->Read(d_status);
	bsi->Read(power);
	bsi->Read(remoteDevT.x);
	bsi->Read(remoteDevT.y);
	bsi->Read(remoteDevV.x);
	bsi->Read(remoteDevV.y);
	bsi->Read(remoteDevA);
}

void FlyObject::SerializationIncrement(BitStream* bso)
{
	bso->Write(id);
	bso->Write(status);
	bso->Write(d_status);
}

void FlyObject::DeSerializationIncrement(BitStream* bsi)
{
	bsi->Read(status);
	bsi->Read(d_status);
}

void FlyObject::TakeEffect(VulcanEquip* vulcan)
{
	if (toDestroy) return;
	if (netIO->IsServer())
	{
		armor -= 0.3f * (2 - shield->GetPercentage());
		if (armor < 0) {
			armor = 0.f;
			Die();
		}
		UpdateArmor();
	}
}

void FlyObject::TakeEffect(Weapon* weapon)
{
	if (toDestroy) return;
	if (side == weapon->GetHost()->side) return;
	if (netIO->IsServer())
	{
		armor -= 0.25f * (2 - shield->GetPercentage());
		if (armor < 0) {
			armor = 0.f;
			Die();
		}
		UpdateArmor();
	}
}

void FlyObject::TakeEffect(FlyObject* fObj) {
	if (toDestroy) return; 
	if (fObj->side == side) return;
	if (netIO->IsServer())
	{
		armor -= 0.05f * (2 - shield->GetPercentage());
		if (armor < 0) {
			armor = 0.f;
			Die();
		}
		UpdateArmor();
	}
}

void FlyObject::HandleShield()
{
	int s = status & M_SHIELD;
	if (s == M_SHIELD)
	{
		if (!shield->isOn()) shield->ShieldOn();
	}
	else {
		if (shield->isOn()) shield->ShieldOff();
	}
}

void FlyObject::UpdateArmor()
{
	BitStream bso;
	bso.Write((uchar)ID_ARMOR_UPDATE);
	bso.Write(id);
	bso.Write(armor);
	netIO->broadcastExcludePlayer(&bso, -1);
}
